﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using devtm.Collections;
using devtm.Configuration.Models;
using devtm.Configuration;
using devtm.Helpers;
using System.Reflection;


namespace devtm.Editor.Configuration.Templates
{
    public static class DictionaryTemplate
    {

        public static TableCollection<Template, string> List;




        public static IEnumerable<PropertyItemAttribute> GetPropertyItemAttribute(PropertyInfo propertyInfo, IElementSection section)
        {

            // find template for more functionality
            Type type = DictionaryTemplate.Get(propertyInfo.ReflectedType, section);

            if (type != null)
            {
                PropertyInfo prop1 = type.GetProperty(propertyInfo.Name);
                if (prop1 != null)
                    foreach (Attribute item in Attribute.GetCustomAttributes(prop1))
                        if (item.GetType().IsOfType(typeof(PropertyItemAttribute)))
                            if (AttributIsForMe(section, item))
                                yield return (PropertyItemAttribute)item;
                
            }

        }



        public static CustomDesignerAttribute GetCustomDesignerAttribute(PropertyInfo propertyInfo, IElementSection section)
        {

            CustomDesignerAttribute ret = null;
            Attribute[] Atts;


            // find template for more functionality
            Type type = DictionaryTemplate.Get(propertyInfo.ReflectedType, section);

            if (type != null)
            {
                PropertyInfo prop1 = type.GetProperty(propertyInfo.Name);
                if (prop1 != null)
                {
                    
                    Atts = Attribute.GetCustomAttributes(prop1);
                    foreach (Attribute item in Atts)
                        if (item.GetType().IsOfType(typeof(CustomDesignerAttribute)))
                            if (AttributIsForMe(section, item))
                                if (ret == null || string.IsNullOrEmpty(ret.PathName))
                                    ret = (CustomDesignerAttribute)item;
                            
                        
                }
            }

            return ret;

        }
        
        public static bool AttributIsForMe(IElementSection section, Attribute ee)
        {

            if (ee is CustomDesignerAttribute)
                return AttributIsForMe(section, (ee as CustomDesignerAttribute));

            else if (ee is PropertyItemAttribute)
                return AttributIsForMe(section, (ee as PropertyItemAttribute));

            return true;
        }

        public static bool AttributIsForMe(IElementSection section, PropertyItemAttribute ee)
        {
            bool ret = (bool)ee.CanAssignMethodInfo.Invoke(null, new object[] { section });
            return ret;
        }

        public static bool AttributIsForMe(IElementSection section, CustomDesignerTypeAttribute ee)
        {
            if (string.IsNullOrEmpty(ee.PathName))
                return true;

            else
                if (ComparePath(section, ee.PathName))
                    return true;

            return false;
        }

        public static bool AttributIsForMe(IElementSection section, CustomDesignerAttribute ee)
        {
            if (string.IsNullOrEmpty(ee.PathName))
                return true;

            else
                if (ComparePath(section, ee.PathName))
                    return true;

            return false;
        }



        private static bool ComparePath(IElementSection section, string path)
        {

            if (path.ToLower() == section.Path.ToLower())
                return true;

            if (section.ParentItem != null)
                return ComparePath(section.ParentItem, path);

            return false;

        }


        public static Type Get(Type type, IElementSection section)
        {

            Template obj = null;
            Path path = null;

            if (List.TryGet(type.AssemblyQualifiedName, out obj))
                if (obj.Path.TryGet(section.Path, out path))
                    return path.Type;
                else
                    foreach (Path item in obj.Path)
                        if (string.IsNullOrEmpty(item.PathContext))
                            return item.Type;
                    
                
            if (section.ParentItem != null)
                return Get(type, section.ParentItem);

            return null;

        }


        public static void Init()
        {

            List = new TableCollection<Template, string>(c => c.Name);

            List.GetIndex(c => c.Name );
            

            foreach (Type type in typeof(DictionaryTemplate).Assembly.GetTypes())
            {

                TemplateDesignerAttribute aa =
                    (TemplateDesignerAttribute)Attribute
                        .GetCustomAttribute(type, typeof(TemplateDesignerAttribute));

                if (aa == null)
                    continue;

                Template t = List.Add(
                    new Template() 
                        { Name = aa.TypeName }
                    );

                t.Path.Add(new Path(aa.Path, type));

            }

        }

        
    }
}
